package pfc.view.view.formularios;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.TitledBorder;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;

import org.apache.log4j.Logger;

import pfc.utils.CompressUtils;
import pfc.view.Main;
import pfc.view.control.GeraMenuAplicacao;
import pfc.view.model.Icons;
import pfc.view.view.components.view.ImagePanel;
import pfc.view.view.components.view.JFileChooserLastDirectoryAware;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

public class TelaCodificar extends JInternalFrame {

	private static final Logger logger = Logger.getLogger(TelaCodificar.class); //  @jve:decl-index=0:
	
	private JInternalFrame bigThis = this;
	
	private JPanel jContentPane = null;
	private JPanel jPanelOpcoes = null;
	private JPanel jPanelResultado = null;
	private JLabel jLabelPixels = null;
	private JComboBox jComboBoxPixels = null;
	private JCheckBox jCheckBoxComprimir = null;
	private JTextArea jTextAreaDados = null;
	private ImagePanel imagePanel = null;
	private JLabel jLabelDados = null;
	private JPanel jPanelBotoes = null;
	private JButton jButtonCodificar = null;
	private JButton jButtonFechar = null;
	private JLabel jLabelQrcode = null;
	private JLabel jLabelBytes = null;
	private JLabel jLabelBytesArmazenados = null;

	private JScrollPane jScrollPaneDados;  //  @jve:decl-index=0:

	private JFileChooserLastDirectoryAware janelaAbrir;
	/**
	 * This is the xxx default constructor
	 */
	public TelaCodificar() {
		super();
		initialize();
		
		logger.info("Tela de Codificar inicializada");
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(650, 650);
		this.setContentPane(getJContentPane());
		this.setResizable(true);
		this.setMaximizable(true);
        this.setIconifiable(true);
		this.setClosable(true);
		this.setFrameIcon(Icons.ICONEVALE);
		setTitle("Codificar");
		this.addInternalFrameListener(new ListenerTela());
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.weightx = 1.0;
			gridBagConstraints1.weighty = 0.7;
			gridBagConstraints1.fill = GridBagConstraints.BOTH;
			gridBagConstraints1.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints1.gridy = 1;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.fill = GridBagConstraints.BOTH;
			gridBagConstraints.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints.gridwidth = 1;
			gridBagConstraints.weightx = 1.0;
			gridBagConstraints.weighty = 0.3;
			gridBagConstraints.gridy = 0;
			jContentPane = new JPanel();
			jContentPane.setLayout(new GridBagLayout());
			jContentPane.add(getJPanelOpcoes(), gridBagConstraints);
			jContentPane.add(getJPanelResultado(), gridBagConstraints1);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jPanelOpcoes	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanelOpcoes() {
		if (jPanelOpcoes == null) {
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridx = 0;
			gridBagConstraints7.fill = GridBagConstraints.BOTH;
			gridBagConstraints7.gridwidth = 3;
			gridBagConstraints7.gridy = 2;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 0;
			gridBagConstraints6.anchor = GridBagConstraints.WEST;
			gridBagConstraints6.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints6.gridy = 0;
			jLabelDados = new JLabel();
			jLabelDados.setText("Dados a serem codificados:");
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.fill = GridBagConstraints.BOTH;
			gridBagConstraints5.gridy = 1;
			gridBagConstraints5.weightx = 1.0;
			gridBagConstraints5.weighty = 1.0;
			gridBagConstraints5.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints5.gridx = 0;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.gridx = 1;
			gridBagConstraints4.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints4.anchor = GridBagConstraints.NORTHWEST;
			gridBagConstraints4.gridwidth = 2;
			gridBagConstraints4.fill = GridBagConstraints.NONE;
			gridBagConstraints4.gridy = 1;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.fill = GridBagConstraints.NONE;
			gridBagConstraints3.gridy = 0;
			gridBagConstraints3.weightx = 1.0;
			gridBagConstraints3.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints3.anchor = GridBagConstraints.WEST;
			gridBagConstraints3.gridx = 2;
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 1;
			gridBagConstraints2.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints2.anchor = GridBagConstraints.EAST;
			gridBagConstraints2.gridy = 0;
			jLabelPixels = new JLabel();
			jLabelPixels.setText("Pixels:");
			jPanelOpcoes = new JPanel();
			jPanelOpcoes.setLayout(new GridBagLayout());
			jPanelOpcoes.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.blue, 1), "Opções", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
			jPanelOpcoes.add(jLabelPixels, gridBagConstraints2);
			jPanelOpcoes.add(getJComboBoxPixels(), gridBagConstraints3);
			jPanelOpcoes.add(getJCheckBoxComprimir(), gridBagConstraints4);
			jPanelOpcoes.add(getJScrollPaneDados(), gridBagConstraints5);
			jPanelOpcoes.add(jLabelDados, gridBagConstraints6);
			jPanelOpcoes.add(getJPanelBotoes(), gridBagConstraints7);
		}
		return jPanelOpcoes;
	}

	/**
	 * This method initializes jPanelResultado	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanelResultado() {
		if (jPanelResultado == null) {
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.gridx = 0;
			gridBagConstraints13.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints13.fill = GridBagConstraints.BOTH;
			gridBagConstraints13.weightx = 1.0;
			gridBagConstraints13.weighty = 0.7;
			gridBagConstraints13.gridy = 1;
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.gridx = 2;
			gridBagConstraints12.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints12.gridy = 0;
			jLabelBytesArmazenados = new JLabel();
			jLabelBytesArmazenados.setText("XXXX");
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 1;
			gridBagConstraints11.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints11.gridy = 0;
			jLabelBytes = new JLabel();
			jLabelBytes.setText("Bytes armazenados:");
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 0;
			gridBagConstraints10.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints10.anchor = GridBagConstraints.WEST;
			gridBagConstraints10.gridy = 0;
			jLabelQrcode = new JLabel();
			jLabelQrcode.setText("QRCode gerado:");
			jPanelResultado = new JPanel();
			jPanelResultado.setLayout(new GridBagLayout());
			jPanelResultado.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.blue, 1), "Resultado", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, new Font("Dialog", Font.BOLD, 12), new Color(51, 51, 51)));
			jPanelResultado.add(jLabelQrcode, gridBagConstraints10);
			jPanelResultado.add(jLabelBytes, gridBagConstraints11);
			jPanelResultado.add(jLabelBytesArmazenados, gridBagConstraints12);
			jPanelResultado.add(getImagePanel(), gridBagConstraints13);
		}
		return jPanelResultado;
	}

	/**
	 * This method initializes jComboBoxPixels	
	 * 	
	 * @return javax.swing.JComboBox	
	 */
	private JComboBox getJComboBoxPixels() {
		if (jComboBoxPixels == null) {
			
			List pixels = new ArrayList();
			pixels.add(new Integer(100));
			pixels.add(new Integer(200));
			pixels.add(new Integer(300));
			pixels.add(new Integer(350));
			pixels.add(new Integer(400));
			pixels.add(new Integer(500));
			pixels.add(new Integer(1000));
			
			TreeSet set = new TreeSet(pixels);
			jComboBoxPixels = new JComboBox(set.toArray());
			jComboBoxPixels.setPreferredSize(new Dimension(160, 20));
			jComboBoxPixels.setMinimumSize(new Dimension(160, 20));
		}
		return jComboBoxPixels;
	}

	/**
	 * This method initializes jCheckBoxComprimir	
	 * 	
	 * @return javax.swing.JCheckBox	
	 */
	private JCheckBox getJCheckBoxComprimir() {
		if (jCheckBoxComprimir == null) {
			jCheckBoxComprimir = new JCheckBox();
			jCheckBoxComprimir.setText("Comprimir");
		}
		return jCheckBoxComprimir;
	}

	/**
	 * This method initializes jTextAreaDados	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getJTextAreaDados() {
		if (jTextAreaDados == null) {
			jTextAreaDados = new JTextArea();
			jTextAreaDados.setEditable(true);
			jTextAreaDados.setLineWrap(true);
			jTextAreaDados.setText("");
			jTextAreaDados.setFont(new Font("Courier New", Font.PLAIN, 12));
		}
		return jTextAreaDados;
	}
	
	/**
	 * This method initializes jTextAreaDados	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JScrollPane getJScrollPaneDados() {
		if (jScrollPaneDados == null) {
			jScrollPaneDados = new JScrollPane(getJTextAreaDados());
			jScrollPaneDados.setPreferredSize(new Dimension(300, 100));
			jScrollPaneDados.setMinimumSize(new Dimension(300, 100));
		}
		return jScrollPaneDados;
	}
	
	private ImagePanel getImagePanel() {
		if (imagePanel == null) {
			imagePanel = new ImagePanel();
			imagePanel.setLayout(new GridBagLayout());
			imagePanel.setPreferredSize(new Dimension(300, 450));
			imagePanel.setMinimumSize(new Dimension(300, 450));
		}
		return imagePanel;
	}

	/**
	 * This method initializes jPanelBotoes	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanelBotoes() {
		if (jPanelBotoes == null) {
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridx = 1;
			gridBagConstraints9.insets = new Insets(7, 7, 7, 7);
			gridBagConstraints9.gridy = 0;
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.insets = new Insets(7, 7, 7, 7);
			jPanelBotoes = new JPanel();
			jPanelBotoes.setLayout(new GridBagLayout());
			jPanelBotoes.add(getJButtonCodificar(), gridBagConstraints8);
			jPanelBotoes.add(getJButtonFechar(), gridBagConstraints9);
		}
		return jPanelBotoes;
	}

	/**
	 * This method initializes jButtonCodificar	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonCodificar() {
		if (jButtonCodificar == null) {
			jButtonCodificar = new JButton(Icons.EDITAR);
			jButtonCodificar.setText("Codificar");
			
			janelaAbrir = new JFileChooserLastDirectoryAware("ExportacaoDados");
			janelaAbrir.setDialogTitle("Exportar Dados");
			janelaAbrir.setAcceptAllFileFilterUsed(true);
//			janelaAbrir.addChoosableFileFilter(new ExcelFilter());
//			janelaAbrir.addChoosableFileFilter(new CSVFilter());
			jButtonCodificar.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(jComboBoxPixels.getSelectedIndex() != -1){
						int result = janelaAbrir.showSaveDialog(TelaCodificar.this);
						janelaAbrir.setLastDirectory(janelaAbrir.getCurrentDirectory());
//						janelaAbrir.addChoosableFileFilter(new BmpFilter());
						File file = janelaAbrir.getSelectedFile();
						
						
						if(result == JFileChooserLastDirectoryAware.APPROVE_OPTION){
							String extensao = ".bmp";
							final File caminhoComExtensao;
							if(file.getAbsolutePath().endsWith(extensao)){ //aqui lança excessão se o arquivo estiver aberto.
								caminhoComExtensao = file; 
							}else{
								caminhoComExtensao = new File(file.getAbsolutePath().concat(extensao));
							}
							
							Integer pixels = (Integer)(getJComboBoxPixels().getSelectedItem());
							
							String stringToEncode = getJTextAreaDados().getText();
							
							if (stringToEncode.trim().equals("")) {
								JOptionPane.showMessageDialog(Main.instance, "Não há nada a ser codificado", "Atenção", JOptionPane.INFORMATION_MESSAGE);
								return;
							}
							
							for (int i = 0; i < stringToEncode.length(); i++) {
								if ((stringToEncode.charAt(i) > '9' ||
									 stringToEncode.charAt(i) < '0') &&
									 stringToEncode.charAt(i) != '-') {
									
									JOptionPane.showMessageDialog(Main.instance, "O template a ser codificado só pode conter números e/ou o caractere '-'", "Atenção", JOptionPane.INFORMATION_MESSAGE);
									return;
								}
							}
							byte[] encodedBytes = null;
							if (getJCheckBoxComprimir().isSelected()) {
								encodedBytes = CompressUtils.compress(stringToEncode);
								codificar(encodedBytes, pixels.intValue(), caminhoComExtensao);
							} else {
								encodedBytes = CompressUtils.convertTemplateToByteArray(stringToEncode);
								codificar(encodedBytes, pixels.intValue(), caminhoComExtensao);
							}
							
							try {
								getImagePanel().setImage(ImageIO.read(caminhoComExtensao));
								jLabelBytesArmazenados.setText(encodedBytes != null ? "" + encodedBytes.length : "XXXX");
							} catch (IOException e1) {
								e1.printStackTrace();
							}
							
						}
					}else{
						JOptionPane.showMessageDialog(Main.instance, "Escolha um perfil", "Atenção", JOptionPane.INFORMATION_MESSAGE);
					}
				}
			});
			
		}
		return jButtonCodificar;
	}
	
	private void codificar(Object contents, int pixels, File file) {
		QRCodeWriter codeWriter = new QRCodeWriter();
		try {
			int w = pixels;
			int h = pixels;
			
			ByteMatrix byteMatrix = codeWriter.encode(contents, BarcodeFormat.QR_CODE, w, h);
			
			int i = 0;
			int [] imageData = new int[w * h];
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++) {
					
					int r = 0;
					int g = 0;
					int b = 0;
					
					if (byteMatrix.getArray()[y][x] == 0) {
						r = 0;
						g = 0;
						b = 0;
					} else {
						r = 255;
						g = 255;
						b = 255;
					}
					
					imageData[i++] = (255 << 24) | (r << 16) | (g << 8) | b;
				}
			}

			BufferedImage finalImage;
			finalImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);//TYPE_INT_ARGB
			finalImage.setRGB(0, 0, w, h, imageData, 0 ,w);
			try {
				ImageIO.write(finalImage, "bmp", file);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (WriterException e) {
			e.printStackTrace();
		}
	}

	/**
	 * This method initializes jButtonFechar	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonFechar() {
		if (jButtonFechar == null) {
			jButtonFechar = new JButton(Icons.FECHAR);
			jButtonFechar.setText("Fechar");
			jButtonFechar.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					bigThis.setVisible(false);
					GeraMenuAplicacao.getInstance().removeAplicacoesAbertas(bigThis);
				}
			});
		}
		return jButtonFechar;
	}
	
	private class BmpFilter extends javax.swing.filechooser.FileFilter {

		public boolean accept(File file) {
			String fileName = file.getName().toLowerCase();
			return fileName.toLowerCase().endsWith(".bmp")
					|| file.isDirectory();
		}

		public String getDescription() {
			return "Arquivos *.bmp";
		}
		
	}
	
	private class ListenerTela implements InternalFrameListener{

		public void internalFrameActivated(InternalFrameEvent e) {

		}

		public void internalFrameClosed(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameClosing(InternalFrameEvent e) {
			GeraMenuAplicacao.getInstance().removeAplicacoesAbertas(bigThis);
		}

		public void internalFrameDeactivated(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameDeiconified(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameIconified(InternalFrameEvent e) {
			// TODO Auto-generated method stub
		}

		public void internalFrameOpened(InternalFrameEvent e) {
	
		}	
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"
